package com.pic.others.controller;


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pic.common.utils.DateUtils;
import com.pic.common.utils.R;
import com.pic.common.utils.UserContext;
import com.pic.others.config.minio.MinIOUtil;
import com.pic.others.config.xfxh.XfXhConfig;
import com.pic.others.config.xfxh.XfXhStreamClient;
import com.pic.others.constants.category.ConnectionFlaskConstant;
import com.pic.others.domain.Test;
import com.pic.others.domain.dto.flask.FlaskCategoryDTO;
import com.pic.others.domain.dto.flask.FlaskSimilarResDTO;
import com.pic.others.domain.dto.picture.PictureFormDTO;
import com.pic.others.domain.dto.xfxh.MsgDTO;
import com.pic.others.domain.po.*;
import com.pic.others.mapper.RecommendSimilarPictureMapper;
import com.pic.others.mq.XfXhWebSocketListener;
import com.pic.others.service.impl.*;
import com.pic.others.utils.ConnectionFlaskUtils;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.WebSocket;
import org.apache.http.entity.ContentType;
import org.checkerframework.checker.units.qual.C;
import org.python.core.PyFunction;
import org.python.core.PyList;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/test")
public class TestController {
    private final XfXhStreamClient xfXhStreamClient;


    private final XfXhConfig xfXhConfig;

    @Autowired
    MinIOUtil minIOUtil;

    @GetMapping("/uploadiamge")
    public String upLoadImage() throws IOException {
        //要求将这个图片传到minIo中，
        String path = "C:\\Users\\hasee\\Pictures\\bus.jpg";
        File pdfFile = new File(path);

        FileInputStream fileInputStream = new FileInputStream(pdfFile);
        MultipartFile multipartFile = new MockMultipartFile(pdfFile.getName(), pdfFile.getName(),
                ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
        String koshi = minIOUtil.uploadImgFile("picmemo", "koshi", multipartFile, pdfFile.getName());
        log.info(koshi);
        return koshi;


    }

    @GetMapping("/getPictureSize")
    public String getPictureSize() throws Exception {
        // 定义要去掉的前缀
        String prefixToRemove = "/picmemo";
        String originalUrl="/picmemo/1740655261779283970/2023/12/31/86f1ff7276854e1197efb11052993aae.jpg";
        // 检查原始字符串是否以指定前缀开始
        if (originalUrl.startsWith(prefixToRemove)) {
            // 使用substring去掉前缀
            String result = originalUrl.substring(prefixToRemove.length());
        String picmemo = minIOUtil.getPictureSize("picmemo", result);
        System.out.println("size:"+picmemo);

    }
        return "ok";
    }




    @GetMapping("/getUserSize")
    public String getUserSize() throws Exception {
        // 定义要去掉的前缀
        String prefixToRemove = "/picmemo";
        Long originalUrl=1741438277433184258L;
        String picmemo = minIOUtil.getUserSize("picmemo", originalUrl, "/picmemo", true);
        System.out.println(picmemo);
        return "ok";
    }

    @GetMapping("/deleteiamge")
    public boolean deleteImage() throws IOException {
        //要求将这个图片传到minIo中，

        boolean b = minIOUtil.deleteFile("picmemo", "http://192.168.59.131:9000/picmemo/koshi/2023/12/21/fdb8cff52afd43b9befac30c1be6f6e5.jpg");
        return b;

    }


    @GetMapping("/getId")
    public String getUserContext() {
        log.info("线城池的:{}", UserContext.getUser());
        return String.valueOf(UserContext.getUser());
    }

    @GetMapping("/deleteMin")
    public String deleteMinio() {
        minIOUtil.deleteFile("picmemo", "");
        return "ok";
    }

//    @GetMapping("/addMinio")
//    public String addMinio(){
//        try {
//            FileInputStream fileInputStream=new FileInputStream("C:\\Users\\hasee\\Desktop\\resume_goal\\bus.jpg");
//
//            minIOUtil.uploadImgFile();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
//
//    }

    @GetMapping("/testDateTimeUtil")
    public String testDateTimeUtil() {
        LocalDateTime now = LocalDateTime.now();
        log.info("现在的时间是:{}", now);
        LocalDateTime weekEndTime = DateUtils.getWeekEndTime(now);
        log.info("weekend:{}", weekEndTime);
        LocalDate localDate = LocalDate.now();
        log.info("locateDate:{}", localDate);
        return null;
    }

    @GetMapping("/json")
    public String testJson() {
        List<String> list = new ArrayList<>();
        list.add("地址1");
        list.add("地址2");
        list.add("地址3");
        String jsonString = JSONUtil.toJsonStr(list);
        System.out.println("解析为json：" + jsonString);

        // 将json字符串解析为Java对象
        List<String> parsedList = JSONUtil.toList(jsonString, String.class);

        // 输出解析后的Java对象
        for (String s : parsedList) {
            System.out.println(s);
        }

        return jsonString;
    }

    /**
     * 发送问题
     *
     * @param question 问题
     * @return 星火大模型的回答
     */
    @GetMapping("/sendQuestion")
    public String sendQuestion(@RequestParam("question") String question) {
        log.info(question);
        // 如果是无效字符串，则不对大模型进行请求
        if (StrUtil.isBlank(question)) {
            log.info("无效问题，请重新输入");
            return "无效问题，请重新输入";
        }
        // 获取连接令牌
        if (!xfXhStreamClient.operateToken(XfXhStreamClient.GET_TOKEN_STATUS)) {
            log.info("当前大模型连接数过多，请稍后再试");
            return "当前大模型连接数过多，请稍后再试";
        }

        // 创建消息对象
        MsgDTO msgDTO = MsgDTO.createUserMsg(question);
        // 创建监听器
        XfXhWebSocketListener listener = new XfXhWebSocketListener();
        // 发送问题给大模型，生成 websocket 连接
        WebSocket webSocket = xfXhStreamClient.sendMsg(UUID.randomUUID().toString().substring(0, 10), Collections.singletonList(msgDTO), listener);
        if (webSocket == null) {
            // 归还令牌
            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
            return "系统内部错误，请联系管理员";
        }
        try {
            int count = 0;
            // 为了避免死循环，设置循环次数来定义超时时长
            int maxCount = xfXhConfig.getMaxResponseTime() * 5;
            while (count <= maxCount) {
                Thread.sleep(200);
                if (listener.isWsCloseFlag()) {
                    break;
                }
                count++;
            }
            if (count > maxCount) {
                return "大模型响应超时，请联系管理员";
            }
            // 响应大模型的答案
            log.info("listener.getAnswer().toString();" + listener.getAnswer().toString());
            return listener.getAnswer().toString();
        } catch (InterruptedException e) {
            log.error("错误：" + e.getMessage());
            return "系统内部错误，请联系管理员";
        } finally {
            // 关闭 websocket 连接
            webSocket.close(1000, "");
            // 归还令牌
            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
        }
    }

    private static PythonInterpreter interpreter = new PythonInterpreter();

    @GetMapping("/demo1")
    public String demoPy1() {
        Random random = new Random();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(random.nextInt(100));
        }
        interpreter.execfile("F:\\python\\pyRobotLearn\\xianxing\\code\\api\\Demo1.py");

        PyFunction function = interpreter.get("do_sort", PyFunction.class);
        PyObject obj = function.__call__(new PyList(list));

// 假设 obj 是一个 Hutool JSONObject
        String jsonString = obj.toString();

// 将字符串转换为 User 对象
        User user = JSONUtil.toBean(jsonString, User.class);

        log.info(user.toString());
        //讲string使用JSONUtil将他变成User
        return jsonString;
    }

    private final PictureServiceImpl pictureService;

    //    @ApiOperation("测试相似图片")
//    @GetMapping("/tetsRecommandSimilarPicture")
//    public JSONObject testRecommandSimilarPicture(){
//      long userId=1738921287630561281L;
//      Set<Picture>set=new HashSet<>();
//      List<PictureSimilarFlaskDTO>dtos=new ArrayList<>();
//      List<Picture>pictures= Collections.unmodifiableList(pictureService.lambdaQuery().eq(Picture::getUserId, userId).list());
//      for(Picture picture:pictures){
//          PictureSimilarFlaskDTO dto=new PictureSimilarFlaskDTO();
//          dto.setLocate(picture.getLocate());
//          dto.setPictureId(picture.getPicId());
//      }
//      Set<PictureSimilarFlaskDTO>py=new HashSet<>();
//
//        JSONObject data = ConnectionFlaskUtils.getConnectionFlask(ConnectionFlaskConstant.urlPath.GET_SIMILAR_PICTURE,
//                ConnectionFlaskConstant.method.POSTMAPPING,
//                "data", dtos);
//      log.info("data:{}",data);
//      return data;
//    }




//    @ApiOperation("测试相似图片")
//    @GetMapping("/tetsRecommandSimilarPicture")
//    public JSONObject testRecommandSimilarPicture() {
//        log.info("进去了");
//        long userId = 1738921287630561281L;
//        List<Picture> pictures = Collections.unmodifiableList(pictureService.lambdaQuery().eq(Picture::getUserId, userId).list());
//        Set<PictureSimilarFlaskDTO> dtos = new HashSet<>();
//        if(pictures==null)return null;
//        for (int i = 0; i < pictures.size(); i++) {
//            for (int j = i + 1; j < pictures.size(); j++) {
//                FlaskSimilarResDTO resDTO = new FlaskSimilarResDTO(pictures.get(i).getLocate(), pictures.get(j).getLocate());
//                String data = ConnectionFlaskUtils.getConnectionFlask(ConnectionFlaskConstant.urlPath.GET_SIMILAR_PICTURE,
//                        ConnectionFlaskConstant.method.POSTMAPPING,
//                        "data", resDTO);
//                System.out.println(data);//字符串类型的false和true
////                long score = JSONUtil.toBean(jsonString, Long.class);
//                log.info(pictures.get(i).getLocate());
//                log.info(pictures.get(j).getLocate());
//                log.info("score");
//
//            }
//        }
//        return null;
//    }

    private final RecommendSimilarPictureServiceImpl recommendSimilarPictureService;
    private final RecommendSimilarPictureMapper recommendSimilarPictureMapper;

    @ApiOperation("测试推荐相似接口")
    @GetMapping("/tetsRecommandSimilarPicture")
    public JSONObject testRecommandSimilarPicture() {
        log.info("进去了");
        long userId = 1738921287630561281L;
        List<Picture> pictures = Collections.unmodifiableList(pictureService.lambdaQuery().eq(Picture::getUserId, userId).list());
        Set<RecommendSimilarPicture> dtos = new HashSet<>();
        if(pictures==null)
            return null;
        for (int i = 0; i < pictures.size(); i++) {
            for (int j = i + 1; j < pictures.size(); j++) {
                FlaskSimilarResDTO resDTO = new FlaskSimilarResDTO(pictures.get(i).getLocate(), pictures.get(j).getLocate());
                String data = ConnectionFlaskUtils.getConnectionFlask(ConnectionFlaskConstant.urlPath.GET_SIMILAR_PICTURE,
                        ConnectionFlaskConstant.method.POSTMAPPING,
                        "data", resDTO);
                log.info(data);
                if("True".equals(data)){
                    RecommendSimilarPicture similarPicture=new RecommendSimilarPicture();
                    similarPicture.setUserId(userId);
                    similarPicture.setPictureId(pictures.get(i).getPicId());
                    similarPicture.setLocate(pictures.get(i).getLocate());
                    dtos.add(similarPicture);
                    RecommendSimilarPicture similarPicture2=new RecommendSimilarPicture();
                    similarPicture2.setUserId(userId);
                    similarPicture2.setPictureId(pictures.get(j).getPicId());
                    similarPicture2.setLocate(pictures.get(j).getLocate());

                    dtos.add(similarPicture2);
                }

            }
        }
        for(RecommendSimilarPicture save:dtos){
            recommendSimilarPictureService.save(save);
        }
        return null;
    }

    @PostMapping("/getTestCategory")
    public String getTestCategory(){
        long userId = 1738921287630561281L;
        List<Picture> pictures = pictureService.lambdaQuery()
                .eq(Picture::getUserId, userId)
                .last("LIMIT 2")
                .list();
        for(Picture picture:pictures){
            log.info(pictures.toString());
        }
        pictures.get(0).setLocate("http://8.130.9.58:9000/picmemo/test/objects.jpg");
        String data = ConnectionFlaskUtils.getConnectionFlask(ConnectionFlaskConstant.urlPath.GET_KEY_DESCRIBE,
                "POST",
                ConnectionFlaskConstant.key.PICTURE,JSONUtil.parse(pictures)
        );
        log.info(data);

        return "ok";

    }

//    @PostMapping("/SearchByMultimodal")
//    public  String serch(){
//        long userId = 1740655261779283970L;
//
//        List<Picture> pictures = pictureService.lambdaQuery().eq(Picture::getUserId, userId).list();
//        log.info("跨膜态");
//        List<PictureFormDTO>dtos=new ArrayList<>();
//        PictureFormDTO dto1=new PictureFormDTO(1L,"/picmemo/1740655261779283970/2023/12/29/bc276f24ffe74386a6e5b3c38edb62b7.jpeg"
//        );
//        PictureFormDTO dto2=new PictureFormDTO(2L,"/picmemo/1740655261779283970/2023/12/29/a5cf72b109e243509ea54d70f0105aad.jpg");
//        dtos.add(dto1);
//        dtos.add(dto2);
//        Test test=new Test("白头发",dtos);
//
//            String data = ConnectionFlaskUtils.getConnectionFlask("/SearchByMultimodal",
//                    "POST",
//                    ConnectionFlaskConstant.key.PICTURE,JSONUtil.parse(test)
//                    );
//            log.info(data);
//
//        return "ok";
//    }



    @ApiOperation("磨破")
    @GetMapping("/image_Beautification")
    public String image_Beautification(){

        String locate="/picmemo/test/HAndZ.jpg";
        String data = ConnectionFlaskUtils.getConnectionFlask(
                ConnectionFlaskConstant.urlPath.GET_IMAGE_BEAUTIFICATION,
                ConnectionFlaskConstant.method.POSTMAPPING,
                "picture", locate);
        log.info("磨皮返回值为:{}",data);
        return "ok";
    }






    private final CategoryServiceImpl categoryService;
    private final PictureCategoryServiceImpl pictureCategoryService;
    private final PictureDescribeServiceImpl pictureDescribeService;

    @ApiOperation("测试机器学习传参分割")
    @GetMapping("test_json")
    private String testJson2(){
        long userId = 1738921287630561281L;
        List<Picture> pictures = pictureService.lambdaQuery()
                .eq(Picture::getUserId, userId)
                .last("LIMIT 2")
                .list();
        String jsonString = "[{\"name\":[\"datasets/image/known_people/ZHF.jpg\",\"datasets/image/known_people/ZHF.jpg\"]," +
                "\"locate\":\"http://8.130.9.58:9000/picmemo/1738921287630561281/2023/12/25/886d0c47ed0f4d858b015ff2393dd193.jpg\"," +
                "\"number\":2,\"mood\":[\"happy\"],\"genders\":[\"Woman\"],\"race\":[\"white\"],\"others\":{}}, " +
                "{\"name\":[\"datasets/image/known_people/ZHF.jpg\",\"datasets/image/known_people/ZHF.jpg\"," +
                "\"datasets/image/known_people/ZHF.jpg\"],\"locate\":\"http://8.130.9.58:9000/picmemo/1738921287630561281/2023/12/25/9b4b36304fd741b4a67e6cf8ca18fb1c.jpg\"," +
                "\"number\":1,\"mood\":[\"surprise\"],\"genders\":[\"Man\"],\"race\":[\"white\"],\"others\":{\"elephant\":1}}]";

        ObjectMapper objectMapper = new ObjectMapper();

        try {
            List<FlaskCategoryDTO> personList = Arrays.asList(objectMapper.readValue(jsonString, FlaskCategoryDTO[].class));
            // 现在你可以使用 personList 中的数据了
            for (int i=0;i<personList.size();i++) {
                FlaskCategoryDTO person = personList.get(i);
                String describe = null;
                if (person.getNumber() > 0) {
                    describe = person.getNumber() + "人,情绪是" + person.getMood().toString() + "性别是" + person.getGenders().toString();
                    describe = describe.replace("[", "").replace("]", ""); // 去掉【和】字符
                }
                StringBuffer thing = new StringBuffer();
                for (Map.Entry<String, Object> entry : person.getOthers().entrySet()) {
                    thing.append(entry.getKey() + "有" + entry.getValue() + "个,");
                }
                // 将 StringBuffer 转换为 String
                String thingString = thing.toString();
                thingString = thingString.replace("[", "").replace("]", "");

                PictureDescribe pictureDescribe = new PictureDescribe();

                pictureDescribe.setDescription(describe);
                //有人情况下再判断物品

                pictureDescribe.setThing(thingString);
                pictureDescribe.setPicId(pictures.get(i).getPicId());
                pictureDescribeService.save(pictureDescribe);


                if (person.getNumber() > 0) {//这是有人
                    //遍历这是几个人的种类
                    for (int j = 0; j < person.getNumber(); j++) {
                        //遍历实际上是遍历名字加类名
                        Category category;
                        category = categoryService.lambdaQuery().eq(Category::getCategoryEnglish, person.getNames().get(j)).one();
                        if (category == null) {//没有出现过这个的话
                            category = new Category();
                            category.setCategoryEnglish(person.getNames().get(j));
                            category.setCreateTime(LocalDateTime.now());
                            category.setFatherNodeId(81L);
                            categoryService.save(category);
                        }
                        PictureCategory pictureCategory = new PictureCategory();
                        pictureCategory.setPictureId(pictures.get(i).getPicId());
                        pictureCategory.setCategoryId(category.getCategoryId());
                        pictureCategory.setPictureDescribeId(pictureDescribe.getDescribeId());
                        pictureCategoryService.save(pictureCategory);
                    }
                }
                //接下来是物品的分类
                for (Map.Entry<String, Object> entry : person.getOthers().entrySet()) {
                    Category category = categoryService.lambdaQuery().eq(Category::getCategoryEnglish, entry.getKey()).one();
                    PictureCategory pictureCategory=new PictureCategory();
                    pictureCategory.setPictureDescribeId(pictureDescribe.getDescribeId());
                    pictureCategory.setCategoryId(category.getCategoryId());
                    pictureCategory.setPictureId(pictures.get(i).getPicId());
                    pictureCategoryService.save(pictureCategory);
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
    return "ok";

    }


    private final RecommendSimilarPictureServiceImpl similarPictureService;
    @GetMapping("/update")
    public R<Map<Long, List<RecommendSimilarPicture>>> initRecommand() {
//        Long userId = UserContext.getUser();
        Long userId=1740655261779283970L;
        List<Picture> pictures = Collections.unmodifiableList(pictureService.lambdaQuery().eq(Picture::getUserId, userId).list());
        if (pictures == null || pictures.isEmpty()) {
            return R.error("图片为空");
        }

        Map<Long, List<RecommendSimilarPicture>> map = new HashMap<>();
        boolean[] flags = new boolean[pictures.size()];

        for (int i = 0; i < pictures.size(); i++) {
            int k = 0;
            if (!flags[i]) {
                for (int j = i + 1; j < pictures.size(); j++) {
                    if (!flags[j]) {
                        FlaskSimilarResDTO resDTO = new FlaskSimilarResDTO(pictures.get(i).getLocate(), pictures.get(j).getLocate());
                        try {
                            String data = ConnectionFlaskUtils.getConnectionFlask(
                                    ConnectionFlaskConstant.urlPath.GET_SIMILAR_PICTURE,
                                    ConnectionFlaskConstant.method.POSTMAPPING,
                                    "data", resDTO);
                            log.info(data);
                            if ("True".equals(data)) {
                                RecommendSimilarPicture similarPicture = new RecommendSimilarPicture();
                                similarPicture.setUserId(userId);
                                similarPicture.setPictureId(pictures.get(j).getPicId());
                                similarPicture.setLocate(pictures.get(j).getLocate());
                                similarPictureService.save(similarPicture);
                                map.putIfAbsent((long) i, new ArrayList<>());
                                map.get((long) i).add(similarPicture);
                                k++;
                                flags[j] = true;
                            }
                        } catch (Exception e) {
                            log.error("与 Flask 通信时发生异常: {}", e.getMessage(), e);
                            // 处理异常，可能需要根据具体情况进行回滚等操作
                        }
                    }
                }
                if (k > 0) {
                    RecommendSimilarPicture similarPicture2 = new RecommendSimilarPicture();
                    similarPicture2.setUserId(userId);
                    similarPicture2.setPictureId(pictures.get(i).getPicId());
                    similarPicture2.setLocate(pictures.get(i).getLocate());
                    similarPictureService.save(similarPicture2);
                    map.get((long) i).add(similarPicture2);
                }
            }
        }

        return R.success(map);
    }

    @ApiOperation("图片上传")
    @PostMapping("uploadPicture")
    public R<List<Picture>>uploadPicture(){
        List<Picture>pictures=new ArrayList<>();

      return R.success(pictures);
    }

}


